package com.kakarote.hrm.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.kakarote.core.common.Result;
import com.kakarote.core.common.cache.CrmCacheKey;
import com.kakarote.core.common.constant.OrgConstant;
import com.kakarote.core.common.enums.ExamineLabelEnum;
import com.kakarote.core.entity.UserInfo;
import com.kakarote.core.exception.CrmException;
import com.kakarote.core.feign.admin.entity.SimpleDept;
import com.kakarote.core.feign.admin.entity.SimpleUser;
import com.kakarote.core.feign.admin.service.AdminService;
import com.kakarote.core.feign.examine.entity.ExamineInfoVo;
import com.kakarote.core.feign.examine.entity.ExamineRecordReturnVO;
import com.kakarote.core.feign.examine.entity.ExamineRecordSaveBO;
import com.kakarote.core.feign.examine.service.ExamineService;
import com.kakarote.core.feign.oa.entity.ExamineVO;
import com.kakarote.core.servlet.BaseServiceImpl;
import com.kakarote.core.utils.BaseUtil;
import com.kakarote.core.utils.UserCacheUtil;
import com.kakarote.core.utils.UserUtil;
import com.kakarote.hrm.common.HrmCodeEnum;
import com.kakarote.hrm.constant.EmployeeEntryStatusEnum;
import com.kakarote.hrm.constant.LabelGroupEnum;
import com.kakarote.hrm.entity.BO.AddEmployeeFieldManageBO;
import com.kakarote.hrm.entity.BO.AddFileBO;
import com.kakarote.hrm.entity.BO.EmployeeMaterialBO;
import com.kakarote.hrm.entity.BO.UpdateInformationBO;
import com.kakarote.hrm.entity.PO.*;
import com.kakarote.core.feign.hrm.entity.HrmExamine;
import com.kakarote.hrm.constant.HrmExamineStatusEnum;
import com.kakarote.hrm.entity.VO.EmployeeCurrentWorkExperienceVo;
import com.kakarote.hrm.entity.VO.EmployeePostLevelVo;
import com.kakarote.hrm.mapper.HrmEmployeeDataMapper;
import com.kakarote.hrm.mapper.HrmEmployeeFieldMapper;
import com.kakarote.hrm.mapper.HrmExamineMapper;
import com.kakarote.hrm.service.IHrmEmployeeChangeRecordService;
import com.kakarote.hrm.service.IHrmEmployeePostService;
import com.kakarote.hrm.service.IHrmEmployeeService;
import com.kakarote.hrm.service.IHrmExamineService;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.*;

/**
 * hrm业务流程图
 */
@Service
public class HrmExamineServiceImpl  extends BaseServiceImpl<HrmExamineMapper,HrmExamine > implements IHrmExamineService {

    @Resource ExamineService examineService;
    @Resource IHrmEmployeeService hrmEmployeeService;
    @Resource IHrmEmployeeChangeRecordService employeeChangeRecordService;
    @Resource HrmEmployeeFieldMapper hrmEmployeeFieldMapper;
    @Resource HrmEmployeeDataMapper hrmEmployeeDataMapper;
    @Resource AdminService adminService;
    @Resource IHrmEmployeePostService employeePostService;
    @Autowired
    private HrmEmployeeFileServiceImpl hrmEmployeeFileService;
    @Autowired
    private HrmEmployeeWorkExperienceServiceImpl hrmEmployeeWorkExperienceService;


    /**
     * 入职流程
     * @param employee
     */
    @Override
    public Boolean saveHrmEntryExamine(HrmEmployee employee) {
        return this.saveExamineBasicInfo(employee,ExamineLabelEnum.HRM_入职流程,employee.getOrgId(),null,null);
    }
    /**
     * 员工信息修改流程
     * @param employee
     */
    @Override
    public Boolean saveHrmEmployeeInfoChangeExamine(HrmEmployee employee, String formJson) {
        return this.saveExamineBasicInfo(employee,ExamineLabelEnum.HRM_员工信息修改审批,employee.getOrgId(),null,null, formJson);
    }

    /**
     * 员工关键信息修改流程
     * @param employee
     * @param formJson
     * @return
     */
    @Override
    public Boolean saveEmployeeKeyFieldChangeExamine(HrmEmployee employee, String formJson) {
        return this.saveExamineBasicInfo(employee,ExamineLabelEnum.HRM_员工关键字段修改审批,employee.getOrgId(),null,null, formJson);
    }

    /**
     * 员工职位层级调整审批
     * @param employee
     * @param formJson
     * @return
     */
    @Override
    public Boolean saveEmployeePostLevelChangeExamine(HrmEmployee employee, String formJson) {
        return this.saveExamineBasicInfo(employee,ExamineLabelEnum.HRM_员工职位层级调整审批,employee.getOrgId(),null,null, formJson);
    }

    /**
     * 保存离职审批流
     * @param quitInfo
     */
    @Override
    public Boolean saveHrmLeaveExamine(HrmEmployee employee, HrmEmployeeQuitInfo quitInfo){
       return  this.saveExamineBasicInfo(employee,ExamineLabelEnum.HRM_离职流程,employee.getOrgId(),null,null);
    }

    /**
     * 保存人员调动
     * @param employee
     */
    @Override
    public  Boolean saveHrmEmployeeChangeExamine(HrmEmployee employee){
        Long groupOrgId = OrgConstant.GROUP_ORG_ID;
        return this.saveExamineBasicInfo(employee,ExamineLabelEnum.HRM_跨单位人员调动,groupOrgId,null,null);
    }
    /**
     * 保存人员调动
     */
    @Override
    public  Boolean saveHrmEmployeeChangeExamineInner(HrmEmployee employee){
        return this.saveExamineBasicInfo(employee,ExamineLabelEnum.HRM_内部人员调动,employee.getOrgId(),null,null);
    }
    /**
     * 保存调动流程-调入流程
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public Boolean saveHrmEmployeeChangeInExamine(Long flowId,Long recordId){
        //找到hrmExamine对象。
        //recordId->typeId->hrmExamine
        HrmEmployee hrmEmployee = this.getHrmEmployeeByRecordId(recordId);
//        HrmEmployeeChangeRecord record = employeeChangeRecordService.getLastestRecordByEmployeeId(hrmEmployee.getEmployeeId());
        HrmEmployeeChangeRecord record = null;
        // 先从从缓存中查询
        String cacheKey = CrmCacheKey.EXAMINE_CHANGE_RECORD_TEMP_CACHE_KEY + hrmEmployee.getEmployeeId();
        String cacheValue = BaseUtil.getRedis().get(cacheKey);
        if (StrUtil.isNotEmpty(cacheValue)) {
            record = JSON.parseObject(cacheValue, HrmEmployeeChangeRecord.class);
        }
        if (record == null) {
            record = employeeChangeRecordService.getLastestRecordByEmployeeId(hrmEmployee.getEmployeeId());
        }
        Long orgId = getHasExamineOrgId(record.getNewOrg(), ExamineLabelEnum.HRM_跨单位人员调动_调入);
        if(orgId==null){
            return Boolean.FALSE;
        }
        //保留调动记录Json
        Result<ExamineRecordReturnVO> resultVo = examineService.queryExamineRecordInfo(recordId);
        ExamineRecordReturnVO recordVo = resultVo.getData();
        if (recordVo.getTypeId() != null) {
            HrmExamine hrmExamine = this.lambdaQuery().eq(HrmExamine::getExamineId, recordVo.getTypeId()).one();
            if (ObjectUtil.isNotEmpty(hrmExamine.getFormJson())) {
                JSONObject jsonObject = JSONObject.parseObject(hrmExamine.getFormJson());
                if (jsonObject.containsKey("changeRecord")){
                    String changeRecordStr = jsonObject.getString("changeRecord");
                    if (ObjectUtil.isNotEmpty(changeRecordStr)){
                        hrmEmployee.setChangeRecord(JSON.parseObject(changeRecordStr, HrmEmployeeChangeRecord.class));
                    }
                }
            }
        }
        return this.saveExamineBasicInfo(hrmEmployee, ExamineLabelEnum.HRM_跨单位人员调动_调入, orgId,recordId,flowId);
    }
    /**
     * 保存调动流程-调出流程
     */
    @Override
    public Boolean saveHrmEmployeeChangeOutExamine(Long flowId,Long recordId){
        HrmEmployee hrmEmployee = this.getHrmEmployeeByRecordId(recordId);
        Long orgId = getHasExamineOrgId(hrmEmployee.getOrgId(), ExamineLabelEnum.HRM_跨单位人员调动_调出);
        if(orgId==null){
            return Boolean.FALSE;
        }
        //保留调动记录Json
        Result<ExamineRecordReturnVO> resultVo = examineService.queryExamineRecordInfo(recordId);
        ExamineRecordReturnVO recordVo = resultVo.getData();
        if (recordVo.getTypeId() != null) {
            HrmExamine hrmExamine = this.lambdaQuery().eq(HrmExamine::getExamineId, recordVo.getTypeId()).one();
            if (ObjectUtil.isNotEmpty(hrmExamine.getFormJson())) {
                JSONObject jsonObject = JSONObject.parseObject(hrmExamine.getFormJson());
                if (jsonObject.containsKey("changeRecord")){
                    String changeRecordStr = jsonObject.getString("changeRecord");
                    if (ObjectUtil.isNotEmpty(changeRecordStr)){
                        hrmEmployee.setChangeRecord(JSON.parseObject(changeRecordStr, HrmEmployeeChangeRecord.class));
                    }
                }
            }
        }
        return this.saveExamineBasicInfo(hrmEmployee,ExamineLabelEnum.HRM_跨单位人员调动_调出, orgId,recordId,flowId);
    }
    /**
     * 保存入职流程-企业审批部分
     */
    @Override
    public Boolean saveEmpEntryGroupExamine(Long flowId,Long recordId){
        Long groupOrgId = OrgConstant.GROUP_ORG_ID;
        HrmEmployee hrmEmployee = this.getHrmEmployeeByRecordId(recordId);
        //保留调动记录Json
        Result<ExamineRecordReturnVO> resultVo = examineService.queryExamineRecordInfo(recordId);
        ExamineRecordReturnVO recordVo = resultVo.getData();
        if (recordVo.getTypeId() != null) {
            HrmExamine hrmExamine = this.lambdaQuery().eq(HrmExamine::getExamineId, recordVo.getTypeId()).one();
            if (ObjectUtil.isNotEmpty(hrmExamine.getFormJson())) {
                JSONObject jsonObject = JSONObject.parseObject(hrmExamine.getFormJson());
                if (jsonObject.containsKey("addEmployeeFieldManageBO")){
                    String changeRecordStr = jsonObject.getString("addEmployeeFieldManageBO");
                    if (ObjectUtil.isNotEmpty(changeRecordStr)){
                        hrmEmployee.setAddEmployeeFieldManageBO(JSON.parseObject(changeRecordStr, AddEmployeeFieldManageBO.class));
                    }
                }
            }
        }
        return this.saveExamineBasicInfo(hrmEmployee,ExamineLabelEnum.HRM_下级入职_集团审批,groupOrgId,recordId,flowId);
    }


    /**
     * 根据IDS查询流程Map
     */
    @Override
    public Map<Long, ExamineVO> getHrmExamineByIds(List<Long> hrmExamineIds){
        if(ObjectUtils.isEmpty(hrmExamineIds)){
            return Maps.newHashMap();
        }
        List<HrmExamine> hrmExamines = this.listByIds(hrmExamineIds);
        if(ObjectUtils.isEmpty(hrmExamines)){
            return Maps.newHashMap();
        }
        Map<Long, ExamineVO> res = Maps.newHashMap();
        for (HrmExamine hrmExamine : hrmExamines) {
            ExamineVO examineVO = new ExamineVO();
            BeanUtil.copyProperties(hrmExamine, examineVO);
            wrapExamineVO(examineVO);
            res.put(hrmExamine.getExamineId(),examineVO);
        }
        return res;
    }

    private void wrapExamineVO(ExamineVO examineVO) {
        SimpleUser user = UserCacheUtil.getSimpleUser(examineVO.getCreateUserId());
        examineVO.setCreateUser(user);
            //获取上一步处理人信息
        SimpleUser lastHandleUser = UserCacheUtil.getSimpleUser(examineVO.getLastHandleUserId());
        examineVO.setLastHandleUser(lastHandleUser);
        examineVO.setSubmitDeptName(examineVO.getSubmitDeptName());
        ExamineInfoVo examineInfoVo = examineService.queryExamineById(examineVO.getCategoryId()).getData();
        String title = "";
        if (examineInfoVo != null) {
            title = examineInfoVo.getExamineName();
        }
        examineVO.setCategoryTitle(title);
    }

    /**
     * 根据record,查询对应的数据对象参数
     */
    private HrmEmployee getHrmEmployeeByRecordId(Long recordId){
        //找到hrmExamine对象。
        //recordId->typeId->hrmExamine
        Result<ExamineRecordReturnVO> resultVo = examineService.queryExamineRecordInfo(recordId);
        ExamineRecordReturnVO record = resultVo.getData();
        Long typeId = record.getTypeId();
        HrmExamine hrmExamine = this.getById(typeId);
        if (hrmExamine == null){
            // 从缓存中查询
            String cacheKey = CrmCacheKey.EXAMINE_HRM_EXAMINE_TEMP_CACHE_KEY + typeId;
            String cacheValue = BaseUtil.getRedis().get(cacheKey);
            if (StrUtil.isNotEmpty(cacheValue)) {
                hrmExamine = JSON.parseObject(cacheValue, HrmExamine.class);
            }
        }
        HrmEmployee hrmEmployee = JSON.parseObject(hrmExamine.getFormJson(), HrmEmployee.class);
        hrmEmployee = hrmEmployeeService.getById(hrmEmployee.getEmployeeId());
        return hrmEmployee;
    }
    /**
     * 保存流程基本信息
     * @param employee
     * @param examineLabel
     */
    private Boolean saveExamineBasicInfo(HrmEmployee employee,ExamineLabelEnum examineLabel,Long orgId,Long parentRecordId,Long parentFlowId){
        if (orgId == null) {
            return Boolean.FALSE;
        }
        UserInfo user = UserUtil.getUser();
        //查询当前有效的流程。
        Result<ExamineInfoVo> bizExamine =  examineService.getBizExamine(examineLabel.getCode(), orgId);
        ExamineInfoVo examineInfoVo = bizExamine.getData();
        if(examineInfoVo == null || examineInfoVo.getExamineId()==null){
            return Boolean.FALSE ;
        }
        //新增审批流
        HrmExamine hrmExamine = new HrmExamine();
        hrmExamine.setContent(employee.getEmployeeName()+"的"+examineLabel.getMsg());
        if(user!=null){
            hrmExamine.setRemark(user.getRealname()+"发起的"+employee.getEmployeeName()+"的"+examineLabel.getMsg());
        }
        hrmExamine.setCategoryId(examineInfoVo.getExamineId());
        HrmEmployee emp = new HrmEmployee();
        emp.setEmployeeId(employee.getEmployeeId());
        if (employee.getChangeRecord() != null){
            emp.setChangeRecord(employee.getChangeRecord());
        }
        if (employee.getAddEmployeeFieldManageBO() != null){
            emp.setAddEmployeeFieldManageBO(employee.getAddEmployeeFieldManageBO());
        }
        hrmExamine.setFormJson(JSON.toJSONString(emp));
        this.save(hrmExamine);
        //更新审批的审批记录
        ExamineRecordSaveBO recordSaveBO = new ExamineRecordSaveBO();
        recordSaveBO.setTypeId(hrmExamine.getExamineId());
        recordSaveBO.setCategoryId(examineInfoVo.getExamineId());
        recordSaveBO.setLabel(examineInfoVo.getLabel());
        recordSaveBO.setParentRecordId(parentRecordId);
        recordSaveBO.setParentFlowId(parentFlowId);
        // 将新创建的wk_hrm_examine记录放入缓存，设置60秒过期
        String cacheKey = CrmCacheKey.EXAMINE_HRM_EXAMINE_TEMP_CACHE_KEY + hrmExamine.getExamineId();
        BaseUtil.getRedis().setex(cacheKey, 60, JSON.toJSONString(hrmExamine));
        ExamineRecordReturnVO examineData = examineService.addExamineRecord(recordSaveBO).getData();
        hrmExamine.setExamineRecordId(examineData.getRecordId());
        hrmExamine.setExamineStatus(examineData.getExamineStatus());
        this.updateById(hrmExamine);
        return Boolean.TRUE;
    }

    /**
     * 保存流程基本信息
     * @param employee
     * @param examineLabel
     */
    private Boolean saveExamineBasicInfo(HrmEmployee employee,ExamineLabelEnum examineLabel,Long orgId,Long parentRecordId,Long parentFlowId, String formJson){
        if (orgId == null) {
            return Boolean.FALSE;
        }
        UserInfo user = UserUtil.getUser();
        //查询当前有效的流程。
        Result<ExamineInfoVo> bizExamine =  examineService.getBizExamine(examineLabel.getCode(), orgId);
        ExamineInfoVo examineInfoVo = bizExamine.getData();
        if(examineInfoVo == null || examineInfoVo.getExamineId()==null){
            return Boolean.FALSE ;
        }
        //新增审批流
        HrmExamine hrmExamine = new HrmExamine();
        hrmExamine.setContent(employee.getEmployeeName()+"的"+examineLabel.getMsg());
        if(user!=null){
            hrmExamine.setRemark(user.getRealname()+"发起的"+employee.getEmployeeName()+"的"+examineLabel.getMsg());
        }
        hrmExamine.setCategoryId(examineInfoVo.getExamineId());
        hrmExamine.setFormJson(formJson);
        this.save(hrmExamine);
        //更新审批的审批记录
        ExamineRecordSaveBO recordSaveBO = new ExamineRecordSaveBO();
        recordSaveBO.setTypeId(hrmExamine.getExamineId());
        recordSaveBO.setCategoryId(examineInfoVo.getExamineId());
        recordSaveBO.setLabel(examineInfoVo.getLabel());
        recordSaveBO.setParentRecordId(parentRecordId);
        recordSaveBO.setParentFlowId(parentFlowId);
        ExamineRecordReturnVO examineData = examineService.addExamineRecord(recordSaveBO).getData();
        hrmExamine.setExamineRecordId(examineData.getRecordId());
        hrmExamine.setExamineStatus(examineData.getExamineStatus());
        this.updateById(hrmExamine);
        return Boolean.TRUE;
    }

    /**
     * 向上递归获取,人员调入和调出，一直递归获取到含有的机构
     */
    private Long getHasExamineOrgId(Long currentOrgId,ExamineLabelEnum examineLabel){
        Result<ExamineInfoVo> bizExamine =  examineService.getBizExamine(examineLabel.getCode(), currentOrgId);
        ExamineInfoVo examineInfoVo = bizExamine.getData();
        //存在业务流程
        if(!ObjectUtils.isEmpty(examineInfoVo) && examineInfoVo.getExamineId()!=null){
            return currentOrgId;
        }
        Result<List<SimpleDept>> listResult =  adminService.queryDeptByIds(Lists.newArrayList(currentOrgId));
        List<SimpleDept> simpleDepts = listResult.getData();
        if(ObjectUtils.isEmpty(simpleDepts)){
            return null;
        }
        SimpleDept simpleDept = simpleDepts.get(0);
        Long parentId =simpleDept.getParentId();
        if(parentId.equals(OrgConstant.TOP_ORG_ID)){
              parentId = OrgConstant.GROUP_ORG_ID;
        }
        return getHasExamineOrgId(parentId, examineLabel);
    }

    /**
     * 查询HRM流程信息
     */
    public ExamineVO queryHrmExamineInfo(String examineId) {
        HrmExamine hrmExamine  = this.getById(examineId);
        if (hrmExamine == null) {
            throw new CrmException(HrmCodeEnum.EXAMINE_ALREADY_DELETE);
        }
        ExamineVO examineVO = new ExamineVO();
        BeanUtil.copyProperties(hrmExamine, examineVO);
        SimpleUser simpleUser = UserCacheUtil.getSimpleUser(examineVO.getCreateUserId());
        examineVO.setCreateUser(simpleUser);
        examineVO.setSubmitDeptName(UserCacheUtil.getDeptName(examineVO.getSubmitDeptId()));
        ExamineInfoVo examineInfoVo = examineService.queryExamineById(Long.valueOf(hrmExamine  .getCategoryId())).getData();
        examineVO.setCategoryTitle(examineInfoVo.getExamineName());
        examineVO.setLabel(examineInfoVo.getLabel());
        wrapExamineVO(examineVO);
        return examineVO;
    }

    /**
     * 更新审批流状态
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void finishEntryExamine(Long hrmExamineId,Integer examineStatus){
        this.updateById(new HrmExamine().setExamineId(hrmExamineId).setExamineStatus(examineStatus));
        HrmExamine hrmExamine = this.getById(hrmExamineId);
        HrmEmployee bizObj = JSON.parseObject(hrmExamine.getFormJson(), HrmEmployee.class);
        if(examineStatus  == HrmExamineStatusEnum.PASS.getStatus()){
            hrmEmployeeService.updateEmployeeEntryStatus(bizObj.getEmployeeId(), EmployeeEntryStatusEnum.在职.getValue());
            if (bizObj.getAddEmployeeFieldManageBO() != null && bizObj.getAddEmployeeFieldManageBO().getMaterialList() != null && !bizObj.getAddEmployeeFieldManageBO().getMaterialList().isEmpty()) {
                List<EmployeeMaterialBO> materialList = bizObj.getAddEmployeeFieldManageBO().getMaterialList();
                for (EmployeeMaterialBO materialBO : materialList) {
                    AddFileBO addFileBO = new AddFileBO();
                    addFileBO.setEmployeeId(bizObj.getEmployeeId());
                    addFileBO.setSubType(materialBO.getSubType());
                    addFileBO.setFileId(Long.parseLong(materialBO.getFileId()));
                    hrmEmployeeFileService.addFile(addFileBO);
                }
            }
        }else{
            hrmEmployeeService.updateEmployeeEntryStatus(bizObj.getEmployeeId(), EmployeeEntryStatusEnum.入职驳回.getValue());
        }
        hrmEmployeeService.updateESAfterCommit(bizObj.getEmployeeId());
    }

    /**
     * 完成集团入职流程
     * @param hrmExamineId
     * @param examineStatus
     */
    @Override
    public void  finishGroupEntryExamine(Long hrmExamineId,Integer examineStatus){
        //拒绝，将上级的流程也关闭
        if(examineStatus==HrmExamineStatusEnum.REJECT.getStatus()){
            HrmExamine hrmExamine = this.getById(hrmExamineId);
            Result<ExamineRecordReturnVO> result = examineService.queryExamineRecordInfo(hrmExamine.getExamineRecordId());
            ExamineRecordReturnVO returnVo = result.getData();
            Long parentRecordId = returnVo.getParentRecordId();
            Result<ExamineRecordReturnVO> parentRecordRes = examineService.queryExamineRecordInfo(parentRecordId);
            ExamineRecordReturnVO parentRecord = parentRecordRes.getData();
            //更改父级审批流状态
            this.updateById(new HrmExamine().setExamineId(parentRecord.getTypeId()).setExamineStatus(examineStatus));
            this.entryNotPass(hrmExamineId);
        }
        //更改子级审批流状态
        this.updateById(new HrmExamine().setExamineId(hrmExamineId).setExamineStatus(examineStatus));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void finishEmployeeInfoChangeExamine(Long hrmExamineId, Integer examineStatus) {
        // 审批通过
        if(Objects.equals(examineStatus, HrmExamineStatusEnum.PASS.getStatus())){
            HrmExamine hrmExamine = this.getById(hrmExamineId);
            UpdateInformationBO updateInformationBO = JSON.parseObject(hrmExamine.getFormJson(), UpdateInformationBO.class);
            updateInformationBO.setIsExamine(false);
            hrmEmployeeService.updateInformation(updateInformationBO);
        }
        //更改子级审批流状态
        this.updateById(new HrmExamine().setExamineId(hrmExamineId).setExamineStatus(examineStatus));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void finishEmployeeKeyFieldChangeExamine(Long hrmExamineId, Integer examineStatus) {
        // 审批通过
        if (Objects.equals(examineStatus, HrmExamineStatusEnum.PASS.getStatus())) {
            HrmExamine hrmExamine = this.getById(hrmExamineId);
            String formJson = hrmExamine.getFormJson();
            JSONObject jsonObject = JSONObject.parseObject(formJson);
            String baseParams = jsonObject.getString("baseParams");
            if (StrUtil.isNotEmpty(baseParams)) {
                UpdateInformationBO updateInformationBO = JSON.parseObject(baseParams, UpdateInformationBO.class);
                updateInformationBO.setIsExamine(false);
                hrmEmployeeService.updateInformation(updateInformationBO);
            }
            String postParams = jsonObject.getString("postParams");
            if (StrUtil.isNotEmpty(postParams)) {
                UpdateInformationBO updateInformationBO = JSON.parseObject(postParams, UpdateInformationBO.class);
                updateInformationBO.setIsExamine(false);
                employeePostService.updatePostInformation(updateInformationBO);
            }
        }
        //更改子级审批流状态
        this.updateById(new HrmExamine().setExamineId(hrmExamineId).setExamineStatus(examineStatus));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void finishEmployeePostLevelChangeExamine(Long hrmExamineId, Integer examineStatus) {
        // 审批通过
        if(Objects.equals(examineStatus, HrmExamineStatusEnum.PASS.getStatus())){
            HrmExamine hrmExamine = this.getById(hrmExamineId);
            EmployeePostLevelVo employeePostLevelVo = JSON.parseObject(hrmExamine.getFormJson(), EmployeePostLevelVo.class);
            //保存员工资料附件
            List<EmployeeMaterialBO> materialList = employeePostLevelVo.getMaterialList();
            if (materialList != null && !materialList.isEmpty()){
                for (EmployeeMaterialBO materialBO : materialList) {
                    AddFileBO addFileBO = new AddFileBO();
                    addFileBO.setEmployeeId(employeePostLevelVo.getEmployeeId());
                    addFileBO.setSubType(materialBO.getSubType());
                    addFileBO.setFileId(Long.parseLong(materialBO.getFileId()));
                    hrmEmployeeFileService.addFile(addFileBO);
                }
            }
            changeEmployeeData(LocalDate.now().toString(), employeePostLevelVo.getEmployeeId(), "date_of_employment_level");
            hrmEmployeeService.updateEmployeePostLevel(employeePostLevelVo);
        }
        //更改子级审批流状态
        this.updateById(new HrmExamine().setExamineId(hrmExamineId).setExamineStatus(examineStatus));
    }

    /**
     * 完成离职流程
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void finishLeaveExamine(Long hrmExamineId,Integer examineStatus){
        this.updateById(new HrmExamine().setExamineId(hrmExamineId).setExamineStatus(examineStatus));
        if(examineStatus  == HrmExamineStatusEnum.PASS.getStatus()){
            HrmExamine hrmExamine = this.getById(hrmExamineId);
            HrmEmployee bizObj = JSON.parseObject(hrmExamine.getFormJson(), HrmEmployee.class);
            hrmEmployeeService.updateEmployeeEntryStatus(bizObj.getEmployeeId(), EmployeeEntryStatusEnum.待离职.getValue());
            hrmEmployeeService.updateESAfterCommit(bizObj.getEmployeeId());
        }
    }
    /**
     * 人员调动终止
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public  void finishEmployeeChange(Long hrmExamineId,Integer examineStatus){
        if(examineStatus==HrmExamineStatusEnum.PASS.getStatus()){
            this.employeeChangePass(hrmExamineId);
        }else{
            this.employeeChangeNotPass(hrmExamineId);
        }
        //更改审批流状态
        this.updateById(new HrmExamine().setExamineId(hrmExamineId).setExamineStatus(examineStatus));
    }
    /**
     * 内部流程处理完成
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void  finishChildrenFlow(Long hrmExamineId,Integer examineStatus){
        //拒绝，将上级的流程也关闭
        if(examineStatus==HrmExamineStatusEnum.REJECT.getStatus()){
            HrmExamine hrmExamine = this.getById(hrmExamineId);
            Result<ExamineRecordReturnVO> result = examineService.queryExamineRecordInfo(hrmExamine.getExamineRecordId());
            ExamineRecordReturnVO returnVo = result.getData();
            Long parentRecordId = returnVo.getParentRecordId();
            Result<ExamineRecordReturnVO> parentRecordRes = examineService.queryExamineRecordInfo(parentRecordId);
            ExamineRecordReturnVO parentRecord = parentRecordRes.getData();
            //更改父级审批流状态
            this.updateById(new HrmExamine().setExamineId(parentRecord.getTypeId()).setExamineStatus(examineStatus));
            this.employeeChangeNotPass(hrmExamineId);
        }
        //更改子级审批流状态
        this.updateById(new HrmExamine().setExamineId(hrmExamineId).setExamineStatus(examineStatus));
    }


    /**
     * 父节点的最后一个流程为引用流程，子节点完成之后，父节点得相应的完成
     * @param hrmExamineId
     * @param examineStatus
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void  finishParentFlow(Long hrmExamineId,Integer examineStatus){
        this.updateById(new HrmExamine().setExamineId(hrmExamineId).setExamineStatus(examineStatus));
    }

    /**
     * 员工变动通过
     */
    private void employeeChangePass(Long hrmExamineId){
        HrmExamine hrmExamine = this.getById(hrmExamineId);
        HrmEmployee bizObj = JSON.parseObject(hrmExamine.getFormJson(), HrmEmployee.class);
        HrmEmployeeChangeRecord record = employeeChangeRecordService.getLastestRecordByEmployeeId(bizObj.getEmployeeId());
        //新增人员工作经历
        EmployeeCurrentWorkExperienceVo employeeCurrentWorkExperience = hrmEmployeeService.queryCurrentWorkExperience(bizObj.getEmployeeId());
        HrmEmployeeWorkExperience workExperience = new HrmEmployeeWorkExperience();
        BeanUtil.copyProperties(employeeCurrentWorkExperience, workExperience);
        workExperience.setWorkEndTime(LocalDate.now());
        hrmEmployeeWorkExperienceService.save(workExperience);
        //保存变动记录
        if (record.getNewDept() != null) {
            changeDept(record,"dept");
        }
        if (record.getNewOrg() != null) {
            changeDept(record,"org");
        }
        HrmEmployee hrmEmployee = new HrmEmployee();
        hrmEmployee.setEmployeeId(bizObj.getEmployeeId());
        hrmEmployee.setEntryStatus(EmployeeEntryStatusEnum.在职.getValue());
        hrmEmployee.setOrgId(record.getNewOrg());//修改单位
        hrmEmployee.setDeptId(record.getNewDept()); //修改部门
        //更新员工任职日期、任职级日期、入司时间
        ExamineInfoVo examineInfoVo = examineService.queryExamineById(hrmExamine.getCategoryId()).getData();
        if(examineInfoVo.getLabel() == ExamineLabelEnum.HRM_跨单位人员调动.getCode()){
            //更新员工任职日期、入司时间
            changeEmployeeData(LocalDate.now().toString(), bizObj.getEmployeeId(), "date_of_employment");
            hrmEmployee.setCompanyAgeStartTime(LocalDate.now());
        }
        if(examineInfoVo.getLabel() == ExamineLabelEnum.HRM_内部人员调动.getCode()){
            //更新员工任职日期
            changeEmployeeData(LocalDate.now().toString(), bizObj.getEmployeeId(), "date_of_employment");
        }
        if (bizObj.getChangeRecord() != null ){
            if (StrUtil.isNotBlank(bizObj.getChangeRecord().getNewPost())) {
                changeEmployeePost(bizObj.getChangeRecord(), "job_title");
            }
            if (StrUtil.isNotBlank(bizObj.getChangeRecord().getNewPostLevel())) {
                changeEmployeePost(bizObj.getChangeRecord(), "job_level");
            }
            if (ObjectUtil.isNotEmpty(bizObj.getChangeRecord().getNewPostLevel()) && !Objects.equals(bizObj.getChangeRecord().getOldPostLevel(), bizObj.getChangeRecord().getNewPostLevel())){
                //更新员工职位层级
                changeEmployeeData(LocalDate.now().toString(), bizObj.getEmployeeId(), "date_of_employment_level");
            }
            //保存员工调动资料
            List<EmployeeMaterialBO> materialList = bizObj.getChangeRecord().getMaterialList();
            if (materialList != null && !materialList.isEmpty()){
                for (EmployeeMaterialBO materialBO : materialList) {
                    AddFileBO addFileBO = new AddFileBO();
                    addFileBO.setEmployeeId(bizObj.getEmployeeId());
                    addFileBO.setSubType(materialBO.getSubType());
                    addFileBO.setFileId(Long.parseLong(materialBO.getFileId()));
                    hrmEmployeeFileService.addFile(addFileBO);
                }
            }
        }
        //审核不通过，也还原为在职状态。
        hrmEmployeeService.updateById(hrmEmployee);
        hrmEmployeeService.initEmployeeEsData(Lists.newArrayList(bizObj.getEmployeeId()));
    }

    private void changeEmployeeData(String value, Long employeeId, String fieldName) {
        LambdaQueryWrapper<HrmEmployeeField> hrmEmployeeFieldLambdaQueryWrapper = new LambdaQueryWrapper<>();
        hrmEmployeeFieldLambdaQueryWrapper.eq(HrmEmployeeField::getFieldName, fieldName);
        HrmEmployeeField hrmEmployeeField = hrmEmployeeFieldMapper.selectOne(hrmEmployeeFieldLambdaQueryWrapper);
        if (null != hrmEmployeeField) {
            LambdaQueryWrapper<HrmEmployeeData> hrmEmployeeDataLambdaQueryWrapper = new LambdaQueryWrapper<>();
            hrmEmployeeDataLambdaQueryWrapper.eq(HrmEmployeeData::getFieldId, hrmEmployeeField.getFieldId());
            hrmEmployeeDataLambdaQueryWrapper.eq(HrmEmployeeData::getEmployeeId, employeeId);
            hrmEmployeeDataMapper.delete(hrmEmployeeDataLambdaQueryWrapper);
            HrmEmployeeData hrmEmployeeData = new HrmEmployeeData();
            hrmEmployeeData.setFieldId(hrmEmployeeField.getFieldId());
            hrmEmployeeData.setLabelGroup(LabelGroupEnum.POST.getValue());
            hrmEmployeeData.setName(hrmEmployeeField.getName());
            hrmEmployeeData.setFieldName(hrmEmployeeField.getFieldName());
            hrmEmployeeData.setFieldValue(value);
            hrmEmployeeData.setFieldValueDesc(value);
            hrmEmployeeData.setEmployeeId(employeeId);
            hrmEmployeeDataMapper.insert(hrmEmployeeData);
        }
    }

    private void changeEmployeePost(HrmEmployeeChangeRecord hrmEmployeeChangeRecord, String fieldName) {
        LambdaQueryWrapper<HrmEmployeeField> hrmEmployeeFieldLambdaQueryWrapper = new LambdaQueryWrapper<>();
        hrmEmployeeFieldLambdaQueryWrapper.eq(HrmEmployeeField::getFieldName, fieldName);
        HrmEmployeeField hrmEmployeeField = hrmEmployeeFieldMapper.selectOne(hrmEmployeeFieldLambdaQueryWrapper);
        if (null != hrmEmployeeField) {
            LambdaQueryWrapper<HrmEmployeeData> hrmEmployeeDataLambdaQueryWrapper = new LambdaQueryWrapper<>();
            hrmEmployeeDataLambdaQueryWrapper.eq(HrmEmployeeData::getFieldId, hrmEmployeeField.getFieldId());
            hrmEmployeeDataLambdaQueryWrapper.eq(HrmEmployeeData::getEmployeeId, hrmEmployeeChangeRecord.getEmployeeId());
            hrmEmployeeDataMapper.delete(hrmEmployeeDataLambdaQueryWrapper);
            HrmEmployeeData hrmEmployeeData = new HrmEmployeeData();
            hrmEmployeeData.setFieldId(hrmEmployeeField.getFieldId());
            hrmEmployeeData.setLabelGroup(LabelGroupEnum.POST.getValue());
            hrmEmployeeData.setName(hrmEmployeeField.getName());
            hrmEmployeeData.setFieldName(hrmEmployeeField.getFieldName());
            if ("job_level".equals(fieldName)){
                hrmEmployeeData.setFieldValue(String.valueOf(hrmEmployeeChangeRecord.getNewPostLevel()));
                hrmEmployeeData.setFieldValueDesc(String.valueOf(hrmEmployeeChangeRecord.getNewPostLevel()));
            }else if ("job_title".equals(fieldName)){
                hrmEmployeeData.setFieldValue(String.valueOf(hrmEmployeeChangeRecord.getNewPost()));
                hrmEmployeeData.setFieldValueDesc(String.valueOf(hrmEmployeeChangeRecord.getNewPost()));
            }
            hrmEmployeeData.setEmployeeId((hrmEmployeeChangeRecord.getEmployeeId()));
            hrmEmployeeDataMapper.insert(hrmEmployeeData);
        }
    }

    /**
     * 审核不通过
     * @param hrmExamineId
     */
    private void employeeChangeNotPass(Long hrmExamineId){
        //审核不通过，还原到在职状态。
        HrmExamine hrmExamine = this.getById(hrmExamineId);
        HrmEmployee bizObj = JSON.parseObject(hrmExamine.getFormJson(), HrmEmployee.class);
        HrmEmployee hrmEmployee = new HrmEmployee();
        hrmEmployee.setEmployeeId(bizObj.getEmployeeId());
        hrmEmployee.setEntryStatus(EmployeeEntryStatusEnum.在职.getValue());
        hrmEmployeeService.updateById(hrmEmployee);
        hrmEmployeeService.initEmployeeEsData(Lists.newArrayList(bizObj.getEmployeeId()));
    }

    private void entryNotPass(Long hrmExamineId){
        HrmExamine hrmExamine = this.getById(hrmExamineId);
        HrmEmployee bizObj = JSON.parseObject(hrmExamine.getFormJson(), HrmEmployee.class);
        HrmEmployee hrmEmployee = new HrmEmployee();
        hrmEmployee.setEmployeeId(bizObj.getEmployeeId());
        hrmEmployee.setEntryStatus(EmployeeEntryStatusEnum.入职驳回.getValue());
        hrmEmployeeService.updateById(hrmEmployee);
        hrmEmployeeService.initEmployeeEsData(Lists.newArrayList(bizObj.getEmployeeId()));
    }

    private void changeDept(HrmEmployeeChangeRecord hrmEmployeeChangeRecord, String fieldName){
        // 校验更改的是部门还是机构
        LambdaQueryWrapper<HrmEmployeeField> hrmEmployeeFieldLambdaQueryWrapper = new LambdaQueryWrapper<>();
        hrmEmployeeFieldLambdaQueryWrapper.eq(HrmEmployeeField::getFieldName, fieldName);
        HrmEmployeeField hrmEmployeeField = hrmEmployeeFieldMapper.selectOne(hrmEmployeeFieldLambdaQueryWrapper);
        if (null != hrmEmployeeField) {
            LambdaQueryWrapper<HrmEmployeeData> hrmEmployeeDataLambdaQueryWrapper = new LambdaQueryWrapper<>();
            hrmEmployeeDataLambdaQueryWrapper.eq(HrmEmployeeData::getFieldId, hrmEmployeeField.getFieldId());
            hrmEmployeeDataLambdaQueryWrapper.eq(HrmEmployeeData::getEmployeeId, hrmEmployeeChangeRecord.getEmployeeId());
            hrmEmployeeDataMapper.delete(hrmEmployeeDataLambdaQueryWrapper);
            HrmEmployeeData hrmEmployeeData = new HrmEmployeeData();
            hrmEmployeeData.setFieldName(hrmEmployeeField.getFieldName());
            hrmEmployeeData.setFieldId(hrmEmployeeField.getFieldId());
            hrmEmployeeData.setLabelGroup(LabelGroupEnum.POST.getValue());
            hrmEmployeeData.setName(hrmEmployeeField.getName());
            if(fieldName.equals("org")){
                hrmEmployeeData.setFieldValue(String.valueOf(hrmEmployeeChangeRecord.getNewOrg()));
                hrmEmployeeData.setFieldValueDesc(String.valueOf(hrmEmployeeChangeRecord.getNewOrg()));
            }
            if(fieldName.equals("dept")){
                hrmEmployeeData.setFieldValue(String.valueOf(hrmEmployeeChangeRecord.getNewDept()));
                hrmEmployeeData.setFieldValueDesc(String.valueOf(hrmEmployeeChangeRecord.getNewDept()));
            }
            hrmEmployeeData.setEmployeeId((hrmEmployeeChangeRecord.getEmployeeId()));
            hrmEmployeeDataMapper.insert(hrmEmployeeData);
        }
    }
}
